package cn.uncode.springcloud.starter.web.configuration;


import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import cn.uncode.springcloud.starter.web.exception.RCException;
import cn.uncode.springcloud.starter.web.result.R;
import cn.uncode.springcloud.starter.web.result.ResultCode;
import cn.uncode.springcloud.utils.string.StringUtil;
import feign.FeignException;
import lombok.extern.slf4j.Slf4j;

/**
 * 全局的的异常拦截器
 *
 * @author Juny
 * @date 2018/05/22
 */
@Slf4j
@Configuration
@ControllerAdvice
@RestControllerAdvice
public class GlobalExceptionAutoConfiguration {

    private static final String MATCN_STR = ",\"resultMessage\":";


    /**
     * 全局异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(RCException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public R<?> rcexception(RCException e) {
        log.info("保存业务异常信息 ex=" + e.getMessage(), e);
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        servletRequestAttributes.getResponse().setHeader("resultCode", String.valueOf(e.getResultCode().getCode()));
        return R.failure(e.getResultCode().getCode(), e.getMessage());
    }

    /**
     * 全局异常.
     *
     * @param e
     *         the e
     * @return R
     */
    @ExceptionHandler(FeignException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public R<?> feignException(FeignException e) {
        log.error("保存feign调用异常信息 ex=" + e.getMessage(), e);
        //解message中的信息,"status 500 reading IUserService#searchDetailUserInfo(SearchDetailUserInfoRequest); content: {"code":500,"success":false,"data":{},"message":"测试发出!!!"}"
        String retMsg = e.getMessage();
        if (!StringUtil.isEmpty(retMsg) && retMsg.contains(MATCN_STR)) {
            retMsg = retMsg.substring(retMsg.lastIndexOf(MATCN_STR) + 18, retMsg.length() - 2);
        }
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        servletRequestAttributes.getResponse().setHeader("resultCode", String.valueOf(ResultCode.INTERNAL_SERVER_ERROR.getCode()));
        return R.failure(retMsg);
    }

    /**
     * 全局异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public R<?> validateException(ConstraintViolationException e) {
        log.error("保存全局ConstraintViolationException异常信息 ex=" + e.getMessage(), e);
        String msg = null;
        for(ConstraintViolation<?> cv : e.getConstraintViolations()) {
        	msg = (msg == null) ? cv.getMessage() : msg + "," + cv.getMessage();
        }
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        servletRequestAttributes.getResponse().setHeader("resultCode", String.valueOf(ResultCode.PARAM_VALID_ERROR.getCode()));
        return R.failure(ResultCode.PARAM_VALID_ERROR, msg);
    }
    
    /**
     * 全局异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public R<?> exception(RuntimeException e) {
        log.error("保存全局RuntimeException异常信息 ex=" + e.getMessage(), e);
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        servletRequestAttributes.getResponse().setHeader("resultCode", String.valueOf(ResultCode.INTERNAL_SERVER_ERROR.getCode()));
        return R.failure(e.getMessage());
    }
	
	
    /**
     * 全局异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public R<?> exception(Exception e) {
        log.error("保存全局Exception异常信息 ex=" + e.getMessage(), e);
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        servletRequestAttributes.getResponse().setHeader("resultCode", String.valueOf(ResultCode.INTERNAL_SERVER_ERROR.getCode()));
        return R.failure(e.getMessage());
    }
}
